package com.jtny.nytb.datafilling.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jtny.component.contants.GenericConstants;
import com.jtny.component.dto.CurrentUserDTO;
import com.jtny.component.entity.LocalHolder;
import com.jtny.component.entity.PageParam;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.BeanUtils;
import com.jtny.component.util.CurrentUserUtils;
import com.jtny.component.util.DateUtils;
import com.jtny.nytb.datafilling.dao.CCERCertificateDAO;
import com.jtny.nytb.datafilling.dao.GreenCertificateDAO;
import com.jtny.nytb.datafilling.domain.CCERCertificateDO;
import com.jtny.nytb.datafilling.domain.GreenCertificateDO;
import com.jtny.nytb.datafilling.dto.CCERCertificateDTO;
import com.jtny.nytb.datafilling.dto.GreenCertificateDTO;
import com.jtny.nytb.datafilling.errorcode.CertificateErrorCodeEnum;
import com.jtny.nytb.datafilling.service.CertificateService;
import com.jtny.nytb.datafilling.vo.CCERCertificateVO;
import com.jtny.nytb.datafilling.vo.GreenCertificateVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 证书填报管理bizImpl类
 *
 * @author 智慧能源中心-夏燕强
 * @version 1.0
 * @package com.jtny.nytb.energymonitor.datafilling.biz.impl
 * @fileName CertificateBizImpl.java
 * @createTime 2023年09月22日 13:22
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */

@Service
public class CertificateServiceImpl implements CertificateService {

    @Resource
    CCERCertificateDAO ccerCertificateDAO;

    @Resource
    GreenCertificateDAO greenCertificateDAO;



    /**
     * 分页查询CCER证信息
     *
     * @return
     * @throws ServiceException
     */
    @Override
    public Map<String, Object> queryPageCCER(PageParam param) throws ServiceException {
        if (param == null) {
            param.setPageNo(GenericConstants.DEFAULT_PAGE_NO);
            param.setPageSize(GenericConstants.DEFAULT_PAGE_SIZE);
        }
        //数据库操作
        Map<String, Object> map = queryPage(param);
        return map;
    }

    /**
     * 保存CCER证
     *
     * @param ccerCertificateVO
     * @return
     * @throws ServiceException
     */
    @Override
    public CCERCertificateVO saveCCER(CCERCertificateVO ccerCertificateVO) throws ServiceException {
        //获取当前用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();

        //封装DTO对象
        CCERCertificateDTO ccerCertificateDTO = BeanUtils.copyToObject(ccerCertificateVO, CCERCertificateDTO.class);
        CurrentUserUtils.setCreateDefaultField(ccerCertificateDTO, currentUserDTO);

        //保存
        //数据库操作
        CCERCertificateDTO resultDTO = saveCCER(ccerCertificateDTO);

        //将DTO对象转化为VO对象，并返回
        return BeanUtils.copyToObject(resultDTO, CCERCertificateVO.class);
    }

    /**
     * 修改CCER证
     *
     * @param ccerCertificateVO
     * @throws ServiceException
     */
    @Override
    public void updateCCER(CCERCertificateVO ccerCertificateVO) throws ServiceException {
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();

        //判重
        //数据库操作
        Integer isExist = findCCERIsExist(ccerCertificateVO.getCode(), ccerCertificateVO.getId());
        if (isExist > 0) {
            throw new ServiceException(CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorCode(), CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorMessage());
        }
        //数据库操作
        CCERCertificateDTO ccerCertificateDTO = getCCERById(ccerCertificateVO.getId());
        if (ObjectUtil.isNull(ccerCertificateDTO)) {
            throw new ServiceException(CertificateErrorCodeEnum.CCER_NOT_FIND.getErrorCode(), CertificateErrorCodeEnum.CCER_NOT_FIND.getErrorMessage());
        }
        BeanUtils.copyObject(ccerCertificateVO, ccerCertificateDTO);

        CurrentUserUtils.setUpdateDefaultField(ccerCertificateDTO, currentUserDTO);
        //数据库操作
        updateCCER(ccerCertificateDTO);
    }

    /**
     * 批量删除CCER证
     *
     * @param certificateIdList
     * @throws ServiceException
     */
    @Override
    public void deleteCCER(List<Long> certificateIdList) throws ServiceException {
        for (Long id : certificateIdList) {
            //数据库操作
            CCERCertificateDTO ccerCertificateDTO = getCCERById(id);
            if (ObjectUtil.isNull(ccerCertificateDTO)) {
                throw new ServiceException(CertificateErrorCodeEnum.CCER_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorMessage());
            }
            //获取当前登录用户
            CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
            //封装待修改的统一用户DTO对象
            ccerCertificateDTO.setStatus(GenericStatusEnum.DELETED.getValue());
            CurrentUserUtils.setUpdateDefaultField(ccerCertificateDTO, currentUserDTO);
            //修改操作
            //数据库操作
            updateCCER(ccerCertificateDTO);
        }
    }

    /**
     * 批量使用CCER证
     *
     * @param certificateIdList
     * @return
     * @throws ServiceException
     */
    @Override
    public void disablePageTemplate(List<Long> certificateIdList) throws ServiceException {
        for (Long id : certificateIdList) {
            //数据库操作
            CCERCertificateDTO ccerCertificateDTO = getCCERById(id);
            if (ObjectUtil.isNull(ccerCertificateDTO)) {
                throw new ServiceException(CertificateErrorCodeEnum.CCER_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.CCER_OBJECT_IS_NULL.getErrorMessage());
            }
            //获取当前登录用户
            CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
            //封装待修改的统一用户DTO对象
            ccerCertificateDTO.setStatus(1);
            ccerCertificateDTO.setUsedTime(DateUtils.localDateTimeToTimeStr(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
            CurrentUserUtils.setUpdateDefaultField(ccerCertificateDTO, currentUserDTO);
            //修改操作
            //数据库操作
            updateCCER(ccerCertificateDTO);
        }
    }

    /**
     * 获取绿证信息列表
     *
     * @return
     * @throws ServiceException
     */
    @Override
    public Map<String, Object> queryPageGreenCertificate(PageParam param) throws ServiceException {
        if (param == null) {
            param.setPageNo(GenericConstants.DEFAULT_PAGE_NO);
            param.setPageSize(GenericConstants.DEFAULT_PAGE_SIZE);
        }
        //数据库操作
        Map<String, Object> map = queryPageAndGreenCertificate(param);
        return map;
    }

    /**
     * 保存绿证信息
     *
     * @param greenCertificateVO
     * @return
     * @throws ServiceException
     */
    @Override
    public GreenCertificateVO saveGreenCertificate(GreenCertificateVO greenCertificateVO) throws ServiceException {
        //获取当前用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();

        //封装DTO对象
        GreenCertificateDTO greenCertificateDTO = BeanUtils.copyToObject(greenCertificateVO, GreenCertificateDTO.class);
        CurrentUserUtils.setCreateDefaultField(greenCertificateDTO, currentUserDTO);
        //保存
        //数据库操作
        GreenCertificateDTO resultDTO = saveGreenCertificate(greenCertificateDTO);

        //将DTO对象转化为VO对象，并返回
        return BeanUtils.copyToObject(resultDTO, GreenCertificateVO.class);
    }

    /**
     * 更新绿证信息
     *
     * @param greenCertificateVO
     * @throws ServiceException
     */
    @Override
    public void updateGreenCertificate(GreenCertificateVO greenCertificateVO) throws ServiceException {
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();

        //判重
        //数据库操作
        Integer isExist = findGreenCertificateIsExist(greenCertificateVO.getCode(), greenCertificateVO.getId());
        if (isExist > 0) {
            throw new ServiceException(CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorCode(), CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorMessage());
        }
//数据库操作
        GreenCertificateDTO greenCertificateDTO = getGreenCertificateById(greenCertificateVO.getId());
        if (ObjectUtil.isNull(greenCertificateDTO)) {
            throw new ServiceException(CertificateErrorCodeEnum.GREEN_NOT_FIND.getErrorCode(), CertificateErrorCodeEnum.GREEN_NOT_FIND.getErrorMessage());
        }
        BeanUtils.copyObject(greenCertificateVO, greenCertificateDTO);

        CurrentUserUtils.setUpdateDefaultField(greenCertificateDTO, currentUserDTO);
//数据库操作
        updateGreenCertificate(greenCertificateDTO);
    }

    /**
     * 批量删除绿证
     *
     * @param certificateIds
     * @throws ServiceException
     */
    @Override
    public void deleteGreenCertificate(List<Long> certificateIds) throws ServiceException {
        for (Long id : certificateIds) {
            //数据库操作
            GreenCertificateDTO greenCertificateDTO = getGreenCertificateById(id);
            if (ObjectUtil.isNull(greenCertificateDTO)) {
                throw new ServiceException(CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorMessage());
            }
            //获取当前登录用户
            CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
            //封装待修改的统一用户DTO对象
            greenCertificateDTO.setStatus(GenericStatusEnum.DELETED.getValue());
            CurrentUserUtils.setUpdateDefaultField(greenCertificateDTO, currentUserDTO);

            //修改操作
            //数据库操作
            updateGreenCertificate(greenCertificateDTO);
        }
    }

    /**
     * 批量使用绿证
     *
     * @param certificateIds
     * @return
     * @throws ServiceException
     */
    @Override
    public void enableGreenCertificate(List<Long> certificateIds) throws ServiceException {
        for (Long id : certificateIds) {
            //数据库操作
            GreenCertificateDTO greenCertificateDTO = getGreenCertificateById(id);
            if (ObjectUtil.isNull(greenCertificateDTO)) {
                throw new ServiceException(CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorMessage());
            }
            //获取当前登录用户
            CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
            //封装待修改的DTO对象
            greenCertificateDTO.setStatus(1);
            greenCertificateDTO.setUsedTime(DateUtils.localDateTimeToTimeStr(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
            CurrentUserUtils.setUpdateDefaultField(greenCertificateDTO, currentUserDTO);

            //修改操作
            //数据库操作
            updateGreenCertificate(greenCertificateDTO);
        }
    }

    /**
     * 获取绿证列表
     *
     * @return
     */
    @Override
    public List<GreenCertificateVO> detailGreenList() {
        //数据库操作
        List<GreenCertificateDTO> greenCertificateDTOS = getGreenCertificateList();
        return BeanUtils.copyToList(greenCertificateDTOS, GreenCertificateVO.class);
    }

    /**
     * 获取绿证购买量
     *
     * @return
     */
    @Override
    public Map<String, BigDecimal> countGreen() {
        //数据库操作
        return getCountGreenCertificate();
    }

    /**
     * 获取CCER列表
     *
     * @return
     */
    @Override
    public List<CCERCertificateVO> detailCCERList() {
        //数据库操作
        List<CCERCertificateDTO> ccerCertificateList = getCCERCertificateList();
        return BeanUtils.copyToList(ccerCertificateList, CCERCertificateVO.class);
    }

    /**
     * 获取CCER购买量
     *
     * @return
     */
    @Override
    public Map<String, BigDecimal> countCCER() {
        //数据库操作
        return getCountCCERCertificate();
    }

    /**
     * 分页查询CCER证信息
     *
     * @param param
     * @return
     * @throws ServiceException
     */
    public Map<String, Object> queryPage(PageParam param) throws ServiceException {

        Map<String, Object> map = new HashMap<>();

        Integer start = (param.getPageNo() - 1) * param.getPageSize();
        Integer end = (param.getPageNo()) * param.getPageSize();
        List<CCERCertificateDO> ccerCertificateDOS = ccerCertificateDAO.queryPageCCERCertificate(start, end);
        Integer count = ccerCertificateDAO.countCCERCertificate();
        List<CCERCertificateDTO> ccerCertificateDTOList = BeanUtils.copyToList(ccerCertificateDOS, CCERCertificateDTO.class);

        map.put("totalCount", count);
        map.put("ccerCertificateDTOList", ccerCertificateDTOList);
        map.put("totalPage", (count + param.getPageSize() - 1) / param.getPageSize());
        map.put("pageNo", param.getPageNo());
        map.put("pageSize", param.getPageSize());
        return map;
    }

    /**
     * 保存CCER证信息
     *
     * @param ccerCertificateDTO
     * @return
     * @throws ServiceException
     */
    public CCERCertificateDTO saveCCER(CCERCertificateDTO ccerCertificateDTO) throws ServiceException {
        if (ObjectUtil.isNull(ccerCertificateDTO)) {
            throw new ServiceException(CertificateErrorCodeEnum.CCER_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.CCER_OBJECT_IS_NULL.getErrorMessage());
        }
        //判重
        Integer isRepeat = ccerCertificateDAO.findCCERCertificateIsRepeat(ccerCertificateDTO.getCode(), ccerCertificateDTO.getId());
        if (isRepeat > 0) {
            throw new ServiceException(CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorCode(), CertificateErrorCodeEnum.CCER_CODE_REPEAT.getErrorMessage());
        }

        // 将DTO对象的属性复制给DO对象
        CCERCertificateDO ccerCertificateDO = BeanUtils.copyToObject(ccerCertificateDTO, CCERCertificateDO.class);
        // 保存操作
        ccerCertificateDAO.insert(ccerCertificateDO);

        // 将id设置给DTO对象
        ccerCertificateDTO.setId(ccerCertificateDO.getId());

        return ccerCertificateDTO;
    }

    /**
     * 通过主键id获取CCER证信息
     *
     * @param id
     * @return
     */
    public CCERCertificateDTO getCCERById(Long id) {
        // 通过主键id查询DO对象
        CCERCertificateDO ccerCertificateDO = ccerCertificateDAO.selectById(id);
        return BeanUtils.copyToObject(ccerCertificateDO, CCERCertificateDTO.class);
    }

    /**
     * 更新CCER证
     *
     * @param ccerCertificateDTO
     * @throws ServiceException
     */
    public void updateCCER(CCERCertificateDTO ccerCertificateDTO) throws ServiceException {
        CCERCertificateDO ccerCertificateDO = ccerCertificateDAO.selectById(ccerCertificateDTO.getId());
        // 将DTO对象的属性复制给DO对象
        BeanUtils.copyObject(ccerCertificateDTO, ccerCertificateDO);

        //更新
        ccerCertificateDAO.updateById(ccerCertificateDO);
    }

    /**
     * 获取前5条CCER证信息
     *
     * @return
     * @throws ServiceException
     */
    public List<CCERCertificateDTO> getCCERCertificateList() throws ServiceException {
        List<CCERCertificateDO> ccerCertificateInfos = ccerCertificateDAO.findCCERCertificateInfos();
        return BeanUtils.copyToList(ccerCertificateInfos, CCERCertificateDTO.class);
    }

    /**
     * 判重
     *
     * @param code
     * @return
     */
    public Integer findCCERIsExist(String code, Long id) {
        return ccerCertificateDAO.findCCERCertificateIsRepeat(code, id);
    }

    /**
     * 分页查询绿证信息
     *
     * @param pageParam
     * @return
     * @throws ServiceException
     */
    public Map<String, Object> queryPageAndGreenCertificate(PageParam pageParam) throws ServiceException {
        Map<String, Object> map = new HashMap<>();

        Integer start = (pageParam.getPageNo() - 1) * pageParam.getPageSize();
        Integer end = (pageParam.getPageNo()) * pageParam.getPageSize();
        List<GreenCertificateDO> greenCertificateDOS = greenCertificateDAO.queryPageGreenCertificate(start, end);
        Integer count = ccerCertificateDAO.countCCERCertificate();
        List<GreenCertificateDTO> greenCertificateDTOList = BeanUtils.copyToList(greenCertificateDOS, GreenCertificateDTO.class);

        map.put("totalCount", count);
        map.put("greenCertificateDTOList", greenCertificateDTOList);
        map.put("totalPage", (count + pageParam.getPageSize() - 1) / pageParam.getPageSize());
        map.put("pageNo", pageParam.getPageNo());
        map.put("pageSize", pageParam.getPageSize());
        return map;
    }

    /**
     * 保存绿证信息
     *
     * @param greenCertificateDTO
     * @return
     * @throws ServiceException
     */
    public GreenCertificateDTO saveGreenCertificate(GreenCertificateDTO greenCertificateDTO) throws ServiceException {
        if (ObjectUtil.isNull(greenCertificateDTO)) {
            throw new ServiceException(CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorCode(), CertificateErrorCodeEnum.GREEN_OBJECT_IS_NULL.getErrorMessage());
        }
        //判重
        Integer isRepeat = greenCertificateDAO.findGreenCertificateIsRepeat(greenCertificateDTO.getCode(), greenCertificateDTO.getId());
        if (isRepeat > 0) {
            throw new ServiceException(CertificateErrorCodeEnum.GREEN_CODE_REPEAT.getErrorCode(), CertificateErrorCodeEnum.GREEN_CODE_REPEAT.getErrorMessage());
        }

        // 将DTO对象的属性复制给DO对象
        GreenCertificateDO greenCertificateDO = BeanUtils.copyToObject(greenCertificateDTO, GreenCertificateDO.class);
        // 保存操作
        greenCertificateDAO.insert(greenCertificateDO);

        // 将id设置给DTO对象
        greenCertificateDTO.setId(greenCertificateDO.getId());

        return greenCertificateDTO;
    }

    /**
     * 根据主键id，获取绿证信息
     *
     * @param id
     * @return
     */
    public GreenCertificateDTO getGreenCertificateById(Long id) {
        // 通过主键id查询DO对象
        GreenCertificateDO greenCertificateDO = greenCertificateDAO.selectById(id);
        return BeanUtils.copyToObject(greenCertificateDO, GreenCertificateDTO.class);
    }

    /**
     * 更新绿证信息
     *
     * @param greenCertificateDTO
     * @throws ServiceException
     */
    public void updateGreenCertificate(GreenCertificateDTO greenCertificateDTO) throws ServiceException {
        GreenCertificateDO greenCertificateDO = greenCertificateDAO.selectById(greenCertificateDTO.getId());
        // 将DTO对象的属性复制给DO对象
        BeanUtils.copyObject(greenCertificateDTO, greenCertificateDO);

        //更新
        greenCertificateDAO.updateById(greenCertificateDO);
    }

    /**
     * 获取前5条绿证信息
     *
     * @return
     * @throws ServiceException
     */
    public List<GreenCertificateDTO> getGreenCertificateList() throws ServiceException {
        List<GreenCertificateDO> greenCertificateInfos = greenCertificateDAO.findGreenCertificateInfos();
        return BeanUtils.copyToList(greenCertificateInfos, GreenCertificateDTO.class);
    }

    /**
     * 查重
     *
     * @param code
     * @param
     * @return
     */
    public Integer findGreenCertificateIsExist(String code, Long id) {
        return greenCertificateDAO.findGreenCertificateIsRepeat(code, id);
    }

    /**
     * 获取购买的绿证数量
     *
     * @return
     */
    public Map<String, BigDecimal> getCountGreenCertificate() {
        Map<String, BigDecimal> map = new HashMap<>();
        //获取当年购买量
        DateFormat dateFormat = new SimpleDateFormat("yyyy");
        Date date = new Date();
        String year = dateFormat.format(date);
        List<BigDecimal> countCurrentYear = greenCertificateDAO.countCurrentYear(year);
        BigDecimal currentSum = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(countCurrentYear)) {
            for (BigDecimal x : countCurrentYear) {
                currentSum = currentSum.add(x);
            }
            map.put("currentSum", currentSum);
        } else {
            map.put("currentSum", currentSum);
        }

        //获取累计购买量
        BigDecimal addSum = BigDecimal.ZERO;
        List<BigDecimal> countAll = greenCertificateDAO.countAll();
        if (CollectionUtil.isNotEmpty(countAll)) {
            for (BigDecimal y : countAll) {
                addSum = addSum.add(y);
            }
            map.put("addSum", addSum);
        } else {
            map.put("addSum", addSum);
        }
        return map;
    }

    /**
     * 获取购买的CCER数量
     *
     * @return
     */
    public Map<String, BigDecimal> getCountCCERCertificate() {

        Map<String, BigDecimal> map = new HashMap<>();
        //获取当前持有量
        List<BigDecimal> countCurrent = ccerCertificateDAO.countNotUsed();
        BigDecimal currentSum = BigDecimal.ZERO;
        for (BigDecimal x : countCurrent) {
            currentSum = currentSum.add(x);
        }
        map.put("currentSum", currentSum);

        //获取累计购买量
        BigDecimal addSum = BigDecimal.ZERO;
        List<BigDecimal> countAll = ccerCertificateDAO.countAll();
        if (CollectionUtil.isNotEmpty(countAll)) {
            for (BigDecimal y : countAll) {
                addSum = addSum.add(y);
            }
            map.put("addSum", addSum);
        } else {
            map.put("addSum", addSum);
        }
        return map;
    }
}
